package edu.kit.csl.pisa.datatypes;

/*
This file is part of the PISA Alignment Tool.

Copyright (C) 2013
Karlsruhe Institute of Technology
Cognitive Systems Lab (CSL)
Felix Stahlberg

PISA is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

PISA is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with PISA. If not, see <http://www.gnu.org/licenses/>.
*/

/**
 * This class represents a position in an alignment. A position is well-defined
 * for each element in the target phoneme sequence. Instances of this class
 * are used for iterating through alignments on the target side.
 * 
 * @see SentenceAlignment#eachTargetPhoneme()
 * @see SentenceAlignment#eachTargetWord()
 */
public class AlignmentPosition {
	/*
	 * alignment data
	 */
	private int srcWord; // e_A_0j
	private short srcWordPos; // A_0j
	private int trgtPhoneme; // f_j
	private short trgtWordPos; // A_1j
	private byte trgtRelWordPos; // A_2j
	private short trgtWordLength; // A_3j
	private short trgtWordPhonemePos; // A_4j
	
	/**
	 * Sole constructor. Initializes values such that after calling
	 * {@link #moveToNextWordPosition} the first time, we are at the
	 * first word on the first position.
	 */
	public AlignmentPosition() {
		trgtWordPos = -1;
		
		// Default values indicating invalid state
		srcWord = trgtPhoneme = trgtRelWordPos = -1;
		trgtWordLength = trgtWordPhonemePos = -1;
	}
	
	/**
	 * Move to next phoneme position, assuming that both phonemes are aligned
	 * to the same phoneme.
	 * 
	 * @param trgtPhoneme phoneme at the new position
	 */
	public void moveToNextPhonemePosition(int trgtPhoneme) {
		this.trgtPhoneme = trgtPhoneme;
		trgtWordPhonemePos++;
		// all other parameters stay unchanged
	}
	
	/**
	 * Move to next phoneme position, which is a begin of a new word.
	 * 
	 * @param trgtPhoneme phoneme at the new position
	 * @param srcWord new source word
	 * @param srcWordPos position of the new source word in the source sentence
	 * @param trgtRelWordPos the word position of the new target word, relative
	 * 			to all words aligned to srcWord
	 * @param trgtWordLength length of the new target word
	 */
	public void moveToNextWordPosition(int trgtPhoneme, int srcWord,
			short srcWordPos, byte trgtRelWordPos, short trgtWordLength) {
		this.srcWord = srcWord;
		this.srcWordPos = srcWordPos;
		this.trgtPhoneme = trgtPhoneme;
		this.trgtWordPos++;
		this.trgtRelWordPos = trgtRelWordPos;
		this.trgtWordLength = trgtWordLength;
		this.trgtWordPhonemePos = 0;
	}
	
	/**
	 * Get the aligned source word. This is equal to e_A_0j.
	 * 
	 * @return word id of the aligned source word 
	 */
	public int getSourceWord() {
		return srcWord;
	}
	
	/**
	 * Get the position of the aligned source word in the source sentence. 
	 * This is equal to A_0j.
	 * 
	 * @return absolute position of the source word 
	 */
	public int getSourceWordPosition() {
		return srcWordPos;
	}

	/**
	 * Get the phoneme at the current position. This is equal to f_j.
	 * 
	 * @return word id of the phoneme in the target phoneme sequence 
	 */
	public int getTargetPhoneme() {
		return trgtPhoneme;
	}

	/**
	 * Get the position of target word, which belongs to the phoneme position.
	 * This is equal to A_1j.
	 * 
	 * @return the position of the target word
	 */
	public short getTargetWordPosition() {
		return trgtWordPos;
	}

	/**
	 * Get the relative position of the target word belonging to the phoneme
	 * position. Relative here means relative to all target words aligned to 
	 * the same source word. This is equal to A_2j.
	 * 
	 * @return the relative position of the target word
	 */
	public byte getTargetRelativeWordPosition() {
		return trgtRelWordPos;
	}

	/**
	 * Get the word length of the target word, which belongs to the current
	 * phoneme position. This is equal to A_3j.
	 * 
	 * @return the length of the target word
	 */
	public short getTargetWordLength() {
		return trgtWordLength;
	}

	/**
	 * Get the position of the phoneme relative to the current target word. 
	 * This is equal to A_4j.
	 * 
	 * @return the relative phoneme position
	 */
	public short getTargetWordPhonemePosition() {
		return trgtWordPhonemePos;
	}
}
